using System;
using Moq;
using NUnit.Framework;
using Tycho.Parser.Peg;

namespace Tycho.Parser.Tests.Peg {
    [TestFixture]
    public class TerminalSpecification {
        [Test]
        public void ShouldReturnNullIfNeitherWhitespaceNorTerminalProductionParse () {
            var terminalProduction = new Mock<IProduction> ();

            var terminal = new Terminal (terminalProduction.Object);

            Assert.That (terminal.Parse (" d"), Is.Null);
        }

        [Test]
        public void ShouldParseTerminalProductionWhereWhitespaceFinished () {
            var result = new ParseResult(2, null, null);
            var terminalProduction = new IndexAndContextExpectingProduction(result, 1, null);

            var terminal = new Terminal (terminalProduction);

            Assert.That (terminal.Parse (" d"), Is.EqualTo (result));
        }

        [Test]
        public void ShouldReturnNullIfWhitespaceParsesButTerminalProductionDoesnt () {
            var terminalProduction = new IndexAndContextExpectingProduction(null, 1, null);

            var terminal = new Terminal (terminalProduction);

            Assert.That (terminal.Parse (" d"), Is.Null);
        }

        [Test]
        public void ShouldReturnNullSourceEndsAfterWhitespace () {
            var terminalProduction = new Mock<IProduction> ();

            var terminal = new Terminal (terminalProduction.Object);

            Assert.That (terminal.Parse ("   "), Is.Null);

            terminalProduction
                .Verify (p => p.Parse (It.IsAny<char[]> (), It.IsAny<int> (), It.IsAny<ParseContext> (), It.IsAny<string> (), It.IsAny<ParseEnvironment> ()), Times.Never ());
        }

        [Test]
        public void NameShouldReturnNameOfTerminalProduction () {
            var terminalProduction = new Mock<IProduction> ();

            terminalProduction.SetupGet (t => t.Name).Returns ("name");

            var terminal = new Terminal (terminalProduction.Object);

            Assert.That (terminal.Name, Is.EqualTo ("name"));
        }
    }
}